<?php

namespace App\Task;

use AlibabaCloud\Vcs\V20200515\VcsApiResolver;
use App\Model\DataBackhaulSetting;
use App\Model\DataPaymentBackhaul;
use App\Model\DataSpread;
use App\Model\PlayletBind;
use App\Model\Payment;
use App\Model\SystemOrderDay;
use App\Model\SystemOrderDayCount;
use GuzzleHttp\Client;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\DbConnection\Db;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
use Psr\Log\LoggerInterface;



//#[Crontab(name: "dayPaymentStatisticsTask", rule: "0 1 * * *", callback: "execute", memo: "统计除今日之前的订单所有数据'")]
//#[Crontab(name: "paymentStatisticsTask", rule: "*/10 * * * * *", callback: "execute", memo: "统计订单信息'")]
class PaymentStatisticsTask
{
    protected LoggerInterface $logger;
    public function __construct(protected LoggerFactory $loggerFactory)
    {
        $this->logger = $this->loggerFactory->get('log', 'paymentStatistics');
    }

    public function execute()
    {
        $container = ApplicationContext::getContainer();
        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('default');
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------获取一段时间内的所有订单数据');
        $startDate = date('Y-m-d 00:00:00',time());
        $endDate = date("Y-m-d 23:59:59",time());

        $this->logger->info('开始时间为：'.$startDate);
        $this->logger->info('结束时间为：'.$endDate);
        try {
            $orderKey =  'payment_statistics_live';
            $keyData = $redis->get($orderKey);
            if(!empty($keyData)){
//                $redis->del($orderKey);
                $this->logger->info('存在处理中的订单进程');
                $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取订单进行上报');
                return;
            }else{
                $redis->set($orderKey,1);
            }
            //获取需要处理的订单
            $paymentData = Payment::query()
                ->where('pay_time','>=',$startDate)
                ->where('pay_time','<=',$endDate)
                // ->whereBetween('create_at',[$startDate,$endDate])
                ->orderBy('pay_time')
                ->get();

            if($paymentData->isNotEmpty()) {
                //判断是否
                $this->logger->info('订单的数据为数量为：', [count($paymentData)]);
                $date_Arr = [];
                foreach ($paymentData as $paymentDatum) {
                    $pay_time = $paymentDatum->pay_time;
                    $amount = $paymentDatum->amount;
//                    $this->logger->info('当前订单日期为：'.$pay_time);
//                    $this->logger->info('获取此订单的日期和时间：'.$pay_time);
                    $date = date("Y-m-d",strtotime($pay_time));
                    $hour = date("H",strtotime($pay_time));
//                    $this->logger->info('获取此订单的日期为：'.$date);
//                    $this->logger->info('获取此订单的小时为：'.$hour);
                    //获取此订单的日期和时间
                    $spread_id = $paymentDatum->spread_id;
                    $playlet_id = $paymentDatum->playlet_id ?? 0;
                    $ad_id = $paymentDatum->ad_id ?? 0;
                    $applet_id = $paymentDatum->applet_id ?? 0;
                    //创建一个关于日期的数组
                    if(empty($date_Arr[$date])){
                        $date_Arr[$date] = [];
                    }
                    //创建一个关于日期和小时的数组
                    if(empty($date_Arr[$date][$hour])){
                        $date_Arr[$date][$hour] = [];
                    }

                    //订单金额
                    $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                    //订单总数
                    $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                    //待支付
                    if ($paymentDatum->status == 1) {
                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_wait_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                    }
//                    //已支付
                    if ($paymentDatum->status == 2 || $paymentDatum->status == 4) {

                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);

                        if($paymentDatum->first_recharge == 'Y'){
                            $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'first_user_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                            $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'first_user_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                        }

                        if($paymentDatum->today_first_recharge == 'Y'){
                            $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'today_first_user_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                            $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'today_first_user_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                        }

                        if($paymentDatum->today_after_recharge == 'Y'){
                            $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'today_after_user_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                            $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'today_after_user_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                        }

                        //虚拟支付
                        if ($paymentDatum->pay_type == 1) {
                            $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_virtually_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                            $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_virtually_pay_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                        }
                        //微信支付
                        if ($paymentDatum->pay_type == 2) {
                            $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_wx_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                            $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_wx_pay_amonut',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                        }

                        //抖音支付
                        if ($paymentDatum->pay_type == 3 ||$paymentDatum->pay_type == 4 || $paymentDatum->pay_type == 5 ) {
                            $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'dy_pay_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                            $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'dy_pay_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                        }
                    }
                    //已取消
//                    if ($paymentDatum->status == 3) {
//                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_cannel_count',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
//                    }
//                    //已退款
                    if ($paymentDatum->status == 4) {
                        $date_Arr[$date][$hour] = $this->countOrder($date_Arr[$date][$hour],'order_return_count',$spread_id,$playlet_id,$ad_id,$applet_id);
                        $date_Arr[$date][$hour] = $this->countOrderAmount($date_Arr[$date][$hour],'order_return_pay_amount',$spread_id,$playlet_id,$ad_id,$applet_id,$amount);
                    }
                }

                $insertInfo = array();
                $deleteInfo = array();
                //日期数组
                foreach ($date_Arr as $selectDate => $hourInfo) {
                    //日期下时间数组
                    foreach ($hourInfo as $hour => $hourItem) {
                        //每个小时下
                        $deleteInfo[$selectDate][] = $hour;
                        foreach ($hourItem as $spread_key => $numberInfo) {
                            $spreadData = explode("|###|", $spread_key);
                            $spread_id = $spreadData[0];
                            $playlet_id = $spreadData[1];
                            $ad_id = $spreadData[2];
                            $applet_id = $spreadData[3];
//                            var_dump($spreadData);
                            $coutArray = [];
                            foreach ($numberInfo as $number => $item) {
                                $coutArray[$number] = $item;
                            }
                            $comData = [
                                'data_spread_id' => $spread_id,
                                'playlet_id' => $playlet_id,
                                'ad_id' => $ad_id,
                                'applet_id' => $applet_id,
                                'date'  => $selectDate,
                                'hour'  => $hour,
                            ];
                            $insertmoreData = $comData+$coutArray;
                            $insertInfo[] = $insertmoreData;
                        }
                    }
                }
                if(!empty($insertInfo)){
                    foreach ($insertInfo as $item){
                        $insertAllData[] = [
                            'date' => $item['date'],
                            'hour' => $item['hour'],
                            'data_spread_id' => $item['data_spread_id'],
                            'playlet_id' => $item['playlet_id'],
                            'applet_id' => $item['applet_id'],
                            'ad_id' => $item['ad_id'],
                            'first_user_count' => $item['first_user_count'] ?? 0,
                            'today_first_user_pay_amonut' => $item['today_first_user_pay_amonut'] ?? 0,
                            'today_first_user_pay_count' => $item['today_first_user_pay_count'] ?? 0,
                            'today_after_user_pay_amonut' => $item['today_after_user_pay_amonut'] ?? 0,
                            'today_after_user_pay_count' => $item['today_after_user_pay_count'] ?? 0,
                            'first_user_pay_amonut' => $item['first_user_pay_amonut'] ?? 0,
                            'order_count' => $item['order_count'] ?? 0,
                            'order_wait_pay_count' => $item['order_wait_pay_count'] ?? 0,
                            'order_pay_count' => $item['order_pay_count'] ?? 0,
                            'order_cannel_count' => $item['order_cannel_count'] ?? 0,
                            'order_return_count' => $item['order_return_count'] ?? 0,
                            'order_wx_pay_count' => $item['order_wx_pay_count'] ?? 0,
                            'order_virtually_pay_count' => $item['order_virtually_pay_count'] ?? 0,
                            'order_amount' => $item['order_amount'] ?? 0,
                            'order_wx_pay_amonut' => $item['order_wx_pay_amonut'] ?? 0,
                            'order_virtually_pay_amount' => $item['order_virtually_pay_amount'] ?? 0,
                            'order_return_pay_amount' => $item['order_return_pay_amount'] ?? 0,
                            'dy_pay_count' => $item['dy_pay_count'] ?? 0,
                            'dy_pay_amount' => $item['dy_pay_amount'] ?? 0
                        ];
                    }

                    if(!empty($deleteInfo)) {

                        foreach ($deleteInfo as $date => $hourInfo) {
//                            var_dump($date);
//                            foreach ($hourInfo as $hour) {
//                                var_dump($hour);
                                $this->logger->info('删除今日',[$date]);
                                SystemOrderDay::query()->where(['date' => $date])->delete();
//                            }

                        }
                        if(!empty($insertAllData)){
                            $this->logger->info('插入数据',[count($insertAllData)]);

                            $commonData = [];
                            $count = count($insertAllData);
                            foreach ($insertAllData as $key  => $val){
                                $commonData[] = $val;

                                if(count($commonData) > 2000){
                                    Db::table('system_order_day')->insert($commonData);
                                    $commonData = array();
                                }
                                if($key+1 == $count){
                                    Db::table('system_order_day')->insert($commonData);
                                    $commonData = array();
                                }
                            }
                        }
                    }
                }
            } else{
                $this->logger->info('没有订单需要处理');
            }
            $redis->del($orderKey);

        }catch (\Exception $e){
            $redis->del($orderKey);
            $this->logger->error('请求订单|错误：' . $e->getLine() . '|' . $e->getMessage());
        }
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时获取订单数据');
    }


    public function countOrder($statisData,$arrName,$spread_id,$playlet_id,$ad_id,$applet_id){

        $keyName = $spread_id.'|###|'.$playlet_id.'|###|'.$ad_id.'|###|'.$applet_id;

        if (!empty($statisData[$keyName][$arrName])) {
            $statisData[$keyName][$arrName] += 1;
        } else {
            $statisData[$keyName][$arrName] = 1;
        }
        return $statisData;
    }
    public function countOrderAmount($statisData,$arrName,$spread_id,$playlet_id,$ad_id,$applet_id,$amonut){

        $keyName = $spread_id.'|###|'.$playlet_id.'|###|'.$ad_id.'|###|'.$applet_id;

        if (!empty($statisData[$keyName][$arrName])) {
            $statisData[$keyName][$arrName] += $amonut;
        } else {
            $statisData[$keyName][$arrName] = $amonut;
        }
        return $statisData;
    }
}